<?php

/**
 * 订单号申报服务
 * @author chenshubo
 */
namespace App\Service\VendorClient\OrderDeclareServiceApi;

use App\Service\BaseService;
use App\Model\PssModel\Sysconfig;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;
use App\Service\Code\Normal;
class OrderDeclareServiceApiClient extends BaseService
{ 
    /**
     * 申报接口
     * @param array $params
     * @return mixed
     */
    public function OrderApply( $params = [] )
    {        
        if( empty($params['supplierOrder']) || empty($params['orderItem']) || empty($params['companyInfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderItem or companyInfo");
        }
        
        $orderInfo      = $params['supplierOrder'];
        $orderItem      = $params['orderItem'];
        $order          = $params['order'];
        $companyInfo    = $params['companyInfo'];
        $binfo          = $params['binfo'];
        $company_code   = $companyInfo['company_code'];
        
        //支付时间
        $pay_time       = date('Y-m-d H:i:s',$orderInfo['pay_time']);
        //支付流水号
        $pay_sn         = $orderInfo['pay_sn'];
        
        $config         = config('api.orderdeclare.acount');
        
        $orderEnum      = $config['orderEnum'];
        //生成GUID
        if( $orderEnum == 7 ) {//信通
            $guid = 'CEB311_HNZB_FRHG_'.date("YmdHis")."_0001";
        } else {
            $guid = $this->getGuidOnlyValue();
        }
        
        //获取系统配置
        $sysconfig      = Sysconfig::instance()->rows(['is_show'=>1],['name','code','contents']);
        if( empty($sysconfig) ) {
            return Normal::returnCode(Normal::FAIL,"获取申报配置失败，请核对申报配置是否为空");
        }
        
        $sysConfigMap = [];
        foreach ($sysconfig as $item ) {
            $item['contents'] = @json_decode($item['contents'],true);
            $sysConfigMap[$item['code']] = $item;
            unset($item);
        }
        
        if( !empty($order['payCommanyName']) && !empty($order['payCommanyCode']) ) {
            $payCode = $order['payCommanyCode'];
            $payName = $order['payCommanyName'];
        } else {
            $payCode = $sysConfigMap['pay']['contents']['payCode'];
            $payName = $sysConfigMap['pay']['contents']['payName'];
        }
        
        //处理商品组
        $OrderGoodsList = [];
        //商品金额
        $goodsMoney = 0;
        foreach ($orderItem as $key => $item ) {
            $price      = $item['price'];
            $quantity   = $item['quantity'];
            $totalPrice = bcmul((string)$price, (string)$quantity,2);
            $goodsMoney = bcadd((string)$goodsMoney, (string)$totalPrice,2);
            
            //商品
            $OrderGoodsList[] = [
                'gnum'          => $key+1,
                'itemNo'        => $item['declare_skucode'],
                'itemName'      => $item['declare_goods_name'],
                'gmodel'        => $item['declare_spec'],
                'itemDescribe'  => $item['declare_desc'],
                'barCode'       => $item['declare_barcode'],
                'unit'          => $item['declare_unit_code'],
                'currency'      => $item['declare_currency_code'],
                'country'       => $item['declare_country_code'],
                'qty'           => $quantity,
                'price'         => $price,
                'totalPrice'    => $totalPrice,
                'note'          => NULL,
            ];
        }
        
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        $ActualPaidAmt  = bcadd((string)$goodsMoney,(string) $deliver_money,2);
        //优惠金额
        $discount_money = $orderInfo['discount_money'] < 0 ? - $orderInfo['discount_money'] : $orderInfo['discount_money'] ;
        $ActualPaidAmt  = bcadd((string)$ActualPaidAmt, (string)$discount_money,2);
        //税费
        $tax            = $orderInfo['tax'];
        $ActualPaidAmt  = bcadd((string)$ActualPaidAmt, (string)$tax,2);        
        //订单编号
        $orderNo        = $orderInfo['supplier_dsn'];
        
        $goodsInfo      = current($orderItem);
        
        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        
        //订单
        $OrderHead = [
            'guid'                  => $guid,
            'appType'               => '1',
            'appTime'               => date('YmdHis'),
            'appStatus'             => '2',
            'orderType'             => 'I',
            'orderNo'               => $orderNo,
            'ebpCode'               => $sysConfigMap['ebp']['contents']['ebpCode'],
            'ebpName'               => $sysConfigMap['ebp']['contents']['ebpName'],
            'ebcCode'               => $goodsInfo['ebc_code'],
            'ebcName'               => $goodsInfo['ebc_name'],
            'goodsValue'            => $goodsMoney,
            'freight'               => $deliver_money,
            'discount'              => $discount_money,
            'taxTotal'              => $tax,
            'acturalPaid'           => $ActualPaidAmt,
            'currency'              => '142',
            'buyerRegNo'            => $orderInfo['buyer_realname'],
            'buyerName'             => $orderInfo['buyer_realname'],
            'buyerTelephone'        => $orderInfo['buyer_phone'],
            'buyerIdType'           => '1',
            'buyerIdNumber'         => $orderInfo['buyer_idcard'],
            'payCode'               => $payCode,
            'payName'               => $payName,
            'payTransactionId'      => $pay_sn,
            'batchNumbers'          => NULL,
            'consignee'             => $orderInfo['receive_name'],
            'consigneeTelephone'    => $orderInfo['recveive_phone'],
            'consigneeAddress'      => implode("", [
                $orderInfo['province'],
                $orderInfo['city'],
                $orderInfo['district'],
                $orderInfo['receive_address'],
            ]),
            'consigneeDistrict'     => NULL,
            'note'                  => '',
        ];
        
        //传输企业配置
        $BaseTransfer = [
            'copCode'   => $sysConfigMap['cop']['contents']['copCode'],
            'copName'   => $sysConfigMap['cop']['contents']['copName'],
            'dxpMode'   => $sysConfigMap['cop']['contents']['dxpMode'],
            'dxpId'     => $sysConfigMap['cop']['contents']['dxpId'],
            'note'      => NULL,
        ];
        
        //keyInfo
        $Authentication = [
            'keyInfo' => $sysConfigMap['cop']['contents']['keyInfo']??'',
        ];
        
        //订单申报服务组装数据
        $parameters = [
            'orderEnum'         => $config['orderEnum'],
            'callBackUrl'       => $config['callBackUrl'],
            'orderCode'         => $orderNo,
            'microServiceName'  => $config['microServiceName'],
            'ceb311Message'     => [
                'Order' => [
                    [
                        'OrderHead' => $OrderHead,
                        'OrderList' => $OrderGoodsList,
                    ]
                ],
                'BaseTransfer'      => $BaseTransfer,
                'BaseSubscribe'     => NULL,
                'ExtendMessage'     => NULL,
                'Signature'         => NULL,
                'guid'              => $guid,
                'version'           => '1.0',
            ]
        ];
        
        //信通
        if( $orderEnum != 7 ) {
            $parameters['ceb311Message']['Authentication'] = $Authentication;
        }
        
        $requestParam = [
            'method'    => 'orderDeclare',
            'data'      => $parameters,
        ];
        return $this->execute($requestParam);
    }

    //海关生成唯一guid值
    public function getGuidOnlyValue(){
        $a4 = uniqid().rand(10,99);
        $a4 = $this->insertToStr($a4,4,'-');  //这里是后面两组的唯一值 如5770-A529AD987M
        $a4 = $a4.$this->GetRandStr(1);
        $a1 = $this->GetRandStr(8);
        $a2 = $this->GetRandStr(4);
        $a3 = $this->GetRandStr(4);
        $val = $a1.'-'.$a2.'-'.$a3.'-'.$a4;
        return strtoupper($val);
    }
    
    /**
     * 指定位置插入字符串
     * @param $str  原字符串
     * @param $i    插入位置
     * @param $substr 插入字符串
     * @return string 处理后的字符串
     */
    public function insertToStr($str, $i, $substr){
        $startstr="";
        for($j=0; $j<$i; $j++){
            $startstr .= $str[$j];
        }
        //指定插入位置后的字符串
        $laststr="";
        for ($j=$i; $j<strlen($str); $j++){
            $laststr .= $str[$j];
        }
        //将插入位置前，要插入的，插入位置后三个字符串拼接起来
        $str = $startstr . $substr . $laststr;
        //返回结果
        return $str;
    }
    
    /**
     * 获得指定位数随机数
     * @param $length  指定位数
     * @return string  处理后的字符串
     */
    public function GetRandStr($length){
        $str='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $len=strlen($str)-1;
        $randstr='';
        for($i=0;$i<$length;$i++){
            $num=mt_rand(0,$len);
            $randstr .= $str[$num];
        }
        return $randstr;
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )
    {
        $applyUrl = config("api.orderdeclare.acount.orderDeclareUrl");
        $parameter = [
            [
                'tag'       => 'OrderDeclare',
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $applyUrl,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [],
            ],
        ];
        
        $resTask    = TaskWorker::instance()->addTask($parameter);
        $resTask    = current($resTask);
        $result     = @json_decode($resTask['response']['result'],true);
        $httpCode   = isset($result['declareResult']) && $result['declareResult'] == true ? 200 : 0;
        $msg        = !empty($result) ? ($result['message']??'请求失败') : $resTask['response']['result'] ;
        return Normal::returnCode($httpCode,$msg);
    }
}